﻿/***********************************************************************
 *            Project: {{ProjectNameSpace}}
 *        ProjectName: {{ProjectName}}
 *             Author: CHENGWENJUN
 *              Email: kevin_cwj2008@qq.com
 *         CreateTime: {{CreateTime}}
 *        Description: 暂无
 ***********************************************************************/

using CSRedis;
using Furion.ClayObject.Extensions;
using Furion.DataEncryption;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Sckf.Core.Infrastructure;
using {{ProjectNameSpace}}.Infrastructure;
using {{ProjectNameSpace}}.Models;
using {{ProjectNameSpace}}.RedisCache;
using SqlSugar;
using System.Linq.Expressions;
using Yitter.IdGenerator;

namespace {{ProjectNameSpace}}.ManageApi
{
    /// <summary>
    /// {{ModelClassName}} 接口实现
    /// </summary>
    public partial class {{ModelClassName}}Services : I{{ModelClassName}}Service, IDynamicApiController, ITransient
    {
        /// <summary>
        /// 获取管理员列表
        /// </summary>
        /// <param name="page">当前页</param>
        /// <param name="size">每页条数</param>
        /// <returns></returns>
        [HttpGet, QueryParameters]
        public async Task<PageResult<AdminListDto>> List(int page, int size)
        {
            if (page < 0)
                throw Oops.Oh("参数“页码”不正确", typeof(ArgumentException));
            if (size < 0)
                throw Oops.Oh("参数“每页条数”不正确", typeof(ArgumentException));
            RefAsync<int> totalCount = 0;
            var queryable = _repository.Queryable<{{ModelClassName}}>();

            var result = default(List<Admin>);
            if (page == 0 && size == 0)
            {
                result = await queryable.ToListAsync();
                totalCount = result.Count;
            }
            else
                result = await queryable.ToPageListAsync(page, size, totalCount);
            return new PageResult<AdminListDto>(totalCount,result);
        }

        /// <summary>
        /// 添加{{ModelClassName}}
        /// </summary>
        /// <param name="input">{{ModelClassName}}</param>
        /// <returns></returns>
        [HttpPost]
        [RecordOperationLog, OperationLogSettings("添加{{ModelName_CN}}")]
        public async Task Save({{ModelClassName}}Input input)
        {
            var admin = input.Adapt<Admin>();
            admin.Id = YitIdHelper.NextId();
            admin.Status = (int)Enum_AdminStatus.Normal;
            admin.Password = Functions.EncryptPassword(admin.Id.ToString(), input.Password);
            admin.Create_Time = DateTime.Now;
            var execResult = await _repository.UseTranAsync(async () =>
            {
                //验证用户名是否存在
                var exists = await _repository.Queryable<Admin>().AnyAsync(a => a.Username == input.Username);
                if (exists)
                    throw Oops.Oh("用户名已存在");
                //验证手机号是否存在
                exists = await _repository.Queryable<Admin>().AnyAsync(a => a.Cellphone == input.Cellphone);
                if (exists)
                    throw Oops.Oh("联系电话已存在");
                await _repository.Insertable<Admin>(admin).ExecuteCommandAsync();
            });
            if (!execResult.IsSuccess)
                throw execResult.ErrorException;
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="input">管理员</param>
        /// <returns></returns>
        [HttpPut]
        [RecordOperationLog, OperationLogSettings(Enum_OperationLogType.BeforeAndAfter, false, "修改管理员", typeof(Admin), new string[] { nameof(Admin.Id) }, new string[] { nameof(AdminInput.Id) })]
        public async Task Update(AdminInput input)
        {
            var admin = input.Adapt<Admin>();
            Expression<Func<Admin, object>> ignoreColumns = a => new { a.Username, a.Password, a.Status, a.Create_Time };
            if (!string.IsNullOrEmpty(input.Password))
            {
                if (input.Password.Length < 6)
                    throw Oops.Bah("密码长度不能少于6个字符");
                if (input.Password.Length > 18)
                    throw Oops.Bah("密码长度不能超过18个字符");
                admin.Password = Functions.EncryptPassword(input.Id.ToString(), input.Password);
                ignoreColumns = a => new { a.Username, a.Status, a.Create_Time };
            }
            if (input.Area_Id.HasValue)
            {
                var allArea = await _catalogService.List(Enum_CatalogType.Area);
                if (!allArea.Any(a => a.Id == input.Area_Id.Value))
                    throw Oops.Bah("选择的地区不存在");
            }

            var execResult = await _repository.UseTranAsync(async () =>
            {
                //验证手机号是否存在
                var exists = await _repository.Queryable<Admin>().AnyAsync(a => a.Cellphone == admin.Cellphone && a.Id != admin.Id);
                if (exists)
                    throw Oops.Bah("联系电话已存在");
                await _repository.Updateable<Admin>(admin).IgnoreColumns(ignoreColumns).ExecuteCommandAsync();
            });
            if (!execResult.IsSuccess)
                throw execResult.ErrorException;
        }

        /// <summary>
        /// 批量删除{{ModelName_CN}}
        /// </summary>
        /// <param name="input">ids</param>
        /// <returns></returns>
        [HttpDelete]
        [RecordOperationLog, OperationLogSettings(Enum_OperationLogType.Before, true, "删除{{ModelName_CN}}", typeof({{ModelClassName}}), new string[] { nameof({{ModelClassName}}.Id) }, new string[] { nameof(IdsInput<long>.Ids) })]
        public async Task DeleteMultiple(IdsInput<long> input)
        {
            await _repository.Deleteable<Admin>().Where(a => input.Ids.Contains(a.Id) && a.Username != "admin").ExecuteCommandAsync();
            await ClearLoginCache(_csredis, input.Ids);
        }

        /// <summary>
        /// 删除{{ModelName_CN}}
        /// </summary>
        /// <param name="input">id</param>
        /// <returns></returns>
        [HttpDelete]
        [RecordOperationLog, OperationLogSettings(Enum_OperationLogType.Before, false, "删除{{ModelName_CN}}", typeof({{ModelClassName}}), new string[] { nameof({{ModelClassName}}.Id) }, new string[] { nameof(IdInput<long>.Id) })]
        public async Task Delete(IdInput<long> input)
        {
            await DeleteMultiple(new IdsInput<long>
            {
                Ids = new List<long> { input.Id }
            });
        }
    }

    public partial class {{ModelClassName}}Service
    {
        private readonly SqlSugarClient _repository;
        private readonly CSRedisClient _csredis;

        /// <summary>
        /// {{ModelClassName}}Service
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="csredis"></param>
        public AdminService(ISqlSugarRepository repository, CSRedisClient csredis)
        {
            _repository = repository.Context;
            _csredis = csredis;
        }
    }
}
